package com.ruoyi.cm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.base.domain.bo.BaseBsZdBo;
import com.ruoyi.base.domain.vo.BaseBsZdVo;
import com.ruoyi.base.service.IBaseBsZdService;
import com.ruoyi.cm.domain.CmReport;
import com.ruoyi.cm.domain.bo.CmBdQsCountBo;
import com.ruoyi.cm.domain.bo.CmBsContractInfoBo;
import com.ruoyi.cm.domain.vo.CmBsContractInfoVo;
import com.ruoyi.cm.mapper.CmReportMapper;
import com.ruoyi.cm.service.ICmBsContractInfoService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.cm.domain.bo.CmBsStartAdvanceBo;
import com.ruoyi.cm.domain.vo.CmBsStartAdvanceVo;
import com.ruoyi.cm.domain.CmBsStartAdvance;
import com.ruoyi.cm.mapper.CmBsStartAdvanceMapper;
import com.ruoyi.cm.service.ICmBsStartAdvanceService;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 开工预付款Service业务层处理
 *
 * @author zyb
 * @date 2024-09-28
 */
@RequiredArgsConstructor
@Service
public class CmBsStartAdvanceServiceImpl implements ICmBsStartAdvanceService {

    private final CmBsStartAdvanceMapper baseMapper;
    private final CmReportMapper reportMapper;

    private final IBaseBsZdService baseBsZdService;
    private final ICmBsContractInfoService cmBsContractInfoService;

    /**
     * 查询开工预付款
     */
    @Override
    public CmBsStartAdvanceVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询开工预付款列表
     */
    @Override
    public TableDataInfo<CmBsStartAdvanceVo> queryPageList(CmBsStartAdvanceBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<CmBsStartAdvance> lqw = buildQueryWrapper(bo);
        Page<CmBsStartAdvanceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询开工预付款列表
     */
    @Override
    public List<CmBsStartAdvanceVo> queryList(CmBsStartAdvanceBo bo) {
        LambdaQueryWrapper<CmBsStartAdvance> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<CmBsStartAdvanceVo> listData(CmBsStartAdvanceBo bo) {
        if (ObjectUtils.isNotEmpty(bo.getBdId())){
            CmBsContractInfoBo cmBsContractInfoBo = new CmBsContractInfoBo();
            cmBsContractInfoBo.setBdId(bo.getBdId());
            List<CmBsContractInfoVo> cmBsContractInfoVos = cmBsContractInfoService.queryList(cmBsContractInfoBo);
            BaseBsZdBo baseBsZdBo = new BaseBsZdBo();
            baseBsZdBo.setBdId(bo.getBdId());
            List<BaseBsZdVo> baseBsZdVos = baseBsZdService.queryList(baseBsZdBo);
            if (CollectionUtils.isNotEmpty(baseBsZdVos)){
                //根据标段id查询所有期数的报表管理审批状态；
                List<CmReport> cmReports = reportMapper.selectList(new LambdaQueryWrapper<CmReport>().eq(CmReport::getBdId,bo.getBdId()));
                cmReports = cmReports.stream().filter(e->e.getZdId() == null).collect(Collectors.toList());
                Map<Long, String> qsIdStatusMap = cmReports.stream().collect(Collectors.toMap(CmReport::getQsId, CmReport::getStatus));
                List<CmBsStartAdvanceVo> cmBsStartAdvanceVos = new ArrayList<>();
                for(BaseBsZdVo baseBsZdVo : baseBsZdVos) {
                    //按站点名称过滤
                    if (bo.getZdName() != null && !baseBsZdVo.getName().contains(bo.getZdName())) {
                        continue;
                    }
                    CmBsStartAdvanceVo cmBsStartAdvanceVo = new CmBsStartAdvanceVo();
                    cmBsStartAdvanceVo.setBdId(baseBsZdVo.getBdId());
                    cmBsStartAdvanceVo.setZdId(baseBsZdVo.getId());
                    cmBsStartAdvanceVo.setName(baseBsZdVo.getName());
                    cmBsStartAdvanceVo.setHtje(baseBsZdVo.getZdContractAmount());
                    cmBsStartAdvanceVo.setSjhtje(baseBsZdVo.getZdContractAmountActual());
                    cmBsStartAdvanceVo.setReportFlag("00");
                    cmBsStartAdvanceVo.setStatus("00");
                    cmBsStartAdvanceVos.add(cmBsStartAdvanceVo);
                }
                for(CmBsStartAdvanceVo cmBsStartAdvanceVo : cmBsStartAdvanceVos){
                    LambdaQueryWrapper<CmBsStartAdvance> lqw = Wrappers.lambdaQuery();
                    lqw.eq(cmBsStartAdvanceVo.getZdId() != null, CmBsStartAdvance::getZdId, cmBsStartAdvanceVo.getZdId());
                    CmBsStartAdvanceVo vo = baseMapper.selectVoOne(lqw);
                    if(ObjectUtils.isNotEmpty(vo)){
                        cmBsStartAdvanceVo.setId(vo.getId());
                        cmBsStartAdvanceVo.setQsId(vo.getQsId());
                        cmBsStartAdvanceVo.setQs(vo.getQs());
                        cmBsStartAdvanceVo.setKgyfkjr(vo.getKgyfkjr());
                        cmBsStartAdvanceVo.setKcjljj(vo.getKcjljj());
                        cmBsStartAdvanceVo.setZb(vo.getZb());
                        cmBsStartAdvanceVo.setReportFlag(vo.getReportFlag());
                        cmBsStartAdvanceVo.setRemark(vo.getRemark());
                        if(CollUtil.isNotEmpty(qsIdStatusMap)){
                            cmBsStartAdvanceVo.setStatus(qsIdStatusMap.get(vo.getQsId()));
                        }else{
                            cmBsStartAdvanceVo.setStatus("00");
                        }

                    }
                    if(CollectionUtils.isNotEmpty(cmBsContractInfoVos)){
                        CmBsContractInfoVo contractInfoVo = cmBsContractInfoVos.get(0);
                        //占比
                        if(ObjectUtils.isEmpty(cmBsStartAdvanceVo.getZb()) && ObjectUtils.isNotEmpty(contractInfoVo.getKgyfkbl())){
                            cmBsStartAdvanceVo.setZb(contractInfoVo.getKgyfkbl());
                        }
                        //开工预付款金额=合同金额*开工预付款比例*百分比
                        if( ObjectUtils.isNotEmpty(cmBsStartAdvanceVo.getHtje()) && ObjectUtils.isNotEmpty(cmBsStartAdvanceVo.getZb()) && cmBsStartAdvanceVo.getKgyfkjr()==null){
                            cmBsStartAdvanceVo.setKgyfkjr(cmBsStartAdvanceVo.getHtje().multiply(cmBsStartAdvanceVo.getZb()).multiply(new BigDecimal(0.01)).setScale(2, BigDecimal.ROUND_HALF_UP));
                        }
                        //扣除奖励基金= 扣除奖励基金比例*千分比
                        BigDecimal kcjljj = cmBsStartAdvanceVo.getKcjljj();
                        if((kcjljj == null|| kcjljj.compareTo(BigDecimal.ZERO)==0) && ObjectUtils.isNotEmpty(cmBsStartAdvanceVo.getHtje())&&ObjectUtils.isNotEmpty(contractInfoVo.getKcjljjbl())){
                            cmBsStartAdvanceVo.setKcjljj(cmBsStartAdvanceVo.getHtje().multiply(contractInfoVo.getKcjljjbl()).multiply(new BigDecimal(0.001)).setScale(2, BigDecimal.ROUND_HALF_UP));
                        }
                    }
                }
                //筛选期数
                List<CmBsStartAdvanceVo> collect = new ArrayList<>();
                if (ObjectUtils.isNotEmpty(bo.getQsId())){
                    collect = cmBsStartAdvanceVos.stream().filter(t -> bo.getQsId().equals(t.getQsId())).collect(Collectors.toList());
                }else {
                    collect = BeanUtil.copyToList(cmBsStartAdvanceVos,CmBsStartAdvanceVo.class);
                }
                return collect;
            }
        }

        return null;
    }

    private LambdaQueryWrapper<CmBsStartAdvance> buildQueryWrapper(CmBsStartAdvanceBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CmBsStartAdvance> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getBdId() != null, CmBsStartAdvance::getBdId, bo.getBdId());
        lqw.eq(bo.getHtje() != null, CmBsStartAdvance::getHtje, bo.getHtje());
        lqw.eq(bo.getKgyfkjr() != null, CmBsStartAdvance::getKgyfkjr, bo.getKgyfkjr());
        lqw.eq(bo.getZb() != null, CmBsStartAdvance::getZb, bo.getZb());
        lqw.eq(bo.getKcjljj() != null, CmBsStartAdvance::getKcjljj, bo.getKcjljj());
        lqw.eq(StringUtils.isNotBlank(bo.getReportFlag()), CmBsStartAdvance::getReportFlag, bo.getReportFlag());
        lqw.eq(bo.getSort() != null, CmBsStartAdvance::getSort, bo.getSort());
        return lqw;
    }

    /**
     * 新增开工预付款
     */
    @Override
    public Boolean insertByBo(CmBsStartAdvanceBo bo) {
        CmBsStartAdvance add = BeanUtil.toBean(bo, CmBsStartAdvance.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    @DSTransactional
    public Boolean saveBatch(List<CmBsStartAdvanceBo> boList) {
        List<CmBsStartAdvance> cmBsStartAdvances = BeanUtil.copyToList(boList, CmBsStartAdvance.class);
        boolean flag = baseMapper.insertOrUpdateBatch(cmBsStartAdvances);
        if(flag){
            //更新标段站点期数计量表；
            if(CollUtil.isNotEmpty(boList)){
                CmBsStartAdvance bo = cmBsStartAdvances.stream().findFirst().get();
                CmBdQsCountBo qsCountBo = new CmBdQsCountBo();
                qsCountBo.setBdId(bo.getBdId());
                qsCountBo.setQsId(bo.getQsId());
                CmBdQsCountServiceImpl bdQsCountService = SpringUtils.getBean(CmBdQsCountServiceImpl.class);
                bdQsCountService.updateCountBatch(qsCountBo);
            }
        }
        return flag;
//        boolean flag =false;
//        for (CmBsStartAdvance cmBsStartAdvance : cmBsStartAdvances){
//            if(ObjectUtils.isNotEmpty(cmBsStartAdvance.getId())){
//                flag = baseMapper.updateById(cmBsStartAdvance) > 0;
//                if (!flag){
//                    return flag = false;
//                }
//            }else {
//                flag = baseMapper.insert(cmBsStartAdvance) > 0;
//                if (!flag){
//                    return flag = false;
//                }
//            }
//        }
//        return flag;
    }

    /**
     * 修改开工预付款
     */
    @Override
    public Boolean updateByBo(CmBsStartAdvanceBo bo) {
        CmBsStartAdvance update = BeanUtil.toBean(bo, CmBsStartAdvance.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 修改开工预付款审批状态
     */
    @Override
    public Boolean updateApprovalStatusByBo(CmBsStartAdvanceBo bo) {
        LambdaUpdateWrapper<CmBsStartAdvance> lambdaUpdateWrapper = new LambdaUpdateWrapper();
        lambdaUpdateWrapper.set(CmBsStartAdvance :: getReportFlag,bo.getReportFlag());
        lambdaUpdateWrapper.eq(CmBsStartAdvance :: getBdId,bo.getBdId());
         return baseMapper.update(null,lambdaUpdateWrapper)>0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CmBsStartAdvance entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除开工预付款
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    // 标段关联删除
    @Override
    @DSTransactional
    public void removeQs(CmBsStartAdvanceBo bo) {
        LambdaQueryWrapper<CmBsStartAdvance> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getBdId() != null, CmBsStartAdvance::getBdId, bo.getBdId());
        lqw.eq(bo.getQsId() != null, CmBsStartAdvance::getQsId, bo.getQsId());
        lqw.eq(bo.getQs() != null, CmBsStartAdvance::getQs, bo.getQs());
        List<CmBsStartAdvance> list = baseMapper.selectList(lqw);
        List<CmBdQsCountBo> qsCountBos = new ArrayList<>();
        list.forEach(item -> {
            CmBdQsCountBo qsCountBo = new CmBdQsCountBo();
            qsCountBo.setBdId(item.getBdId());
            qsCountBo.setQsId(item.getQsId());
            qsCountBo.setZdId(item.getZdId());
            qsCountBos.add(qsCountBo);
            item.setQsId(null);
            item.setQs(null);
        });
        baseMapper.insertOrUpdateBatch(list);
        //更新标段期数计算中间值；
        CmBdQsCountServiceImpl bdQsCountService = SpringUtils.getBean(CmBdQsCountServiceImpl.class);
        for(CmBdQsCountBo countBo:qsCountBos){
            bdQsCountService.update(countBo);
        }
    }

    /**
     * 批量删除开工预付款；
     * @param bo
     */
    @Override
    public void removeAdvance(CmBsStartAdvanceBo bo) {
        if (CollUtil.isEmpty(bo.getIds())) {
            return;
        }
        List<CmBsStartAdvance> advances = baseMapper.selectBatchIds(bo.getIds());
        List<CmBdQsCountBo> qsCountBos = new ArrayList<>();
        for (CmBsStartAdvance item : advances) {
            CmBdQsCountBo qsCountBo = new CmBdQsCountBo();
            qsCountBo.setBdId(item.getBdId());
            qsCountBo.setQsId(item.getQsId());
            qsCountBo.setZdId(item.getZdId());
            qsCountBos.add(qsCountBo);
            item.setQsId(null);
            item.setQs(null);
        }
        baseMapper.updateBatchById(advances);
        //更新标段期数计算中间值；
        CmBdQsCountServiceImpl bdQsCountService = SpringUtils.getBean(CmBdQsCountServiceImpl.class);
        for (CmBdQsCountBo countBo : qsCountBos) {
            bdQsCountService.update(countBo);
        }
    }
}
